home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
297_01
/
prbltin.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-30
|
57KB
|
1,842 lines
/* prbltin.c */
/* The builtin predicates are defined here.
* If you want lots of builtins then make several files that
* include prbltin.h.
*/
/* Dec 18 88 HdeF Simplified remove clause so that it expects just one
* argument.
* 12/25/91 HdeF, added repeat,gennum predicates
* 01/01/92 HdeF, added reverse_trace_mode, no_reverse_trace_mode
*/
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include "prtypes.h"
#include "prbltin.h"
#include "prlush.h"
#define ATOMORSTRING "atom or string"
#define CANTOPEN "can't open %s"
#define TOOMANYFILES "Too many open files"
extern subst_ptr_t Subst_mem; /* bottom of (global) variable bindings stack */
extern subst_ptr_t my_Subst_alloc();
extern string_ptr_t get_string();
extern atom_ptr_t Nil;
extern FILE * Curr_infile;
extern FILE * Curr_outfile;
extern node_ptr_t ND_builtin_next_nodeptr;/* from prlush.c */
static int Nbuiltins; /* not used but you could used this to keep track of
the builtins you add */
int Trace_flag; /* used by Ptrace(), Pnotrace(), lush() */
int Tracing_now;
/* This is used to test if an atom is a builtin.
* We rely on the fact that any atom less than LastBuiltin is created by
* a call to make_builtin()
*/
atom_ptr_t LastBuiltin;
/****************************************************************************
make_builtin()
This associates a name used at the interpreter level with a builtin.
****************************************************************************/
void make_builtin(fun, prolog_name)
intfun fun;
char *prolog_name;
{
atom_ptr_t atomptr, intern();
atomptr = intern(prolog_name);
ATOMPTR_BUILTIN(atomptr) = fun;
LastBuiltin = atomptr;
record_pred(atomptr);
Nbuiltins++;
}
/*****************************************************************************
nth_arg()
Returns NULL if error .
Otherwise returns the nth argument of current goal's arguments.
The return value is equal to DerefNode
Obviously one could be more efficient than here.
*****************************************************************************/
node_ptr_t nth_arg(narg)
{
node_ptr_t rest_args;
dereference(Arguments, SubstGoal);
if(NODEPTR_TYPE(DerefNode) != PAIR)
{
return(NULL);
}
rest_args = DerefNode;
--narg;
while(narg)
{
--narg;
dereference(NODEPTR_TAIL(rest_args), DerefSubst);
if(NODEPTR_TYPE(DerefNode) != PAIR)
{
return(NULL);
}
rest_args = DerefNode;
}
dereference(NODEPTR_HEAD(rest_args), DerefSubst);
return(DerefNode);
}
/**********************************************************************
type_first_arg()
Returns true if the type of the first arg to the call is equal
to the argument of the function.
**********************************************************************/
type_first_arg(type)
objtype_t type;
{
dereference(Arguments, SubstGoal);
if(NODEPTR_TYPE(DerefNode) != PAIR)
return(nargerr(1));
else
dereference(NODEPTR_HEAD(DerefNode), DerefSubst);
return(NODEPTR_TYPE(DerefNode) == type);
}
/*-------------------------------------------------------------------*/
/* unify the nth argument of goal with an int of value val */
bind_int(narg, val)
integer val;
{
extern subst_ptr_t Subst_mem;
node_ptr_t nodeptr, get_node();
if(!nth_arg(narg))return(nargerr(narg));
nodeptr = get_node(DYNAMIC);
NODEPTR_TYPE(nodeptr) = INT;
NODEPTR_INT(nodeptr) = val;
return(unify(DerefNode, DerefSubst, nodeptr, Subst_mem));
}
#ifdef CHARACTER
/*-------------------------------------------------------------------*/
/* unify the nth argument of goal with a char of value val */
bind_character(narg, val)
uchar_t val;
{
extern subst_ptr_t Subst_mem;
node_ptr_t nodeptr, get_node();
if(!nth_arg(narg))return(nargerr(narg));
nodeptr = get_node(DYNAMIC);
NODEPTR_TYPE(nodeptr) = CHARACTER;
NODEPTR_CHARACTER(nodeptr) = val;
return(unify(DerefNode, DerefSubst, nodeptr, Subst_mem));
}
#endif
#ifdef REAL
/*-------------------------------------------------------------------*/
/* unify the nth argument of goal with a real of value val */
bind_real(narg, val)
real val;
{
node_ptr_t nodeptr, get_node();
real_ptr_t realptr, get_real();
if(!nth_arg(narg))return(nargerr(narg));
nodeptr = get_node(DYNAMIC);
NODEPTR_TYPE(nodeptr) = REAL;
realptr = get_real(DYNAMIC);
*realptr = val;
NODEPTR_REALP(nodeptr) = realptr;
return(unify(DerefNode, DerefSubst, nodeptr, Subst_mem));
}
#endif
/*-------------------------------------------------------------------*/
/* unify the nth argument of goal with an int of value val */
bind_clause(narg, val)
clause_ptr_t val;
{
node_ptr_t nodeptr, get_node();
extern subst_ptr_t Subst_mem;
if(!nth_arg(narg))return(nargerr(narg));
nodeptr = get_node(DYNAMIC);
NODEPTR_TYPE(nodeptr) = CLAUSE;
NODEPTR_CLAUSE(nodeptr) = val;
return(unify(DerefNode, DerefSubst, nodeptr, Subst_mem));
}
/*-------------------------------------------------------------------*/
/* unify the nth argument of goal with an atom*/
bind_atom(narg, atomptr)
atom_ptr_t atomptr;
{
extern subst_ptr_t Subst_mem;
node_ptr_t nodeptr, get_node();
if(!nth_arg(narg))return(nargerr(narg));
nodeptr = get_node(DYNAMIC);
NODEPTR_TYPE(nodeptr) = ATOM;
NODEPTR_ATOM(nodeptr) = atomptr;
return(unify(DerefNode, DerefSubst, nodeptr, Subst_mem));
}
/*-------------------------------------------------------------------*/
/* unify the nth argument of goal with a copy of the string*/
bind_string(narg, stringptr)
string_ptr_t stringptr;
{
extern subst_ptr_t Subst_mem;
node_ptr_t nodeptr, get_node();
string_ptr_t s;
if(!nth_arg(narg))return(nargerr(narg));
nodeptr = get_node(DYNAMIC);
NODEPTR_TYPE(nodeptr) = STRING;
s = get_string((my_alloc_size_t)strlen(stringptr)+1 , DYNAMIC);
strcpy(s, stringptr);
NODEPTR_STRING(nodeptr) = s;
return(unify(DerefNode, DerefSubst, nodeptr, Subst_mem));
}
/*----------------------------------------------------------------------------
The functions corresponding to the builtins are as follows.
The correct syntax for the call refers to the syntax in
prmanual.txt.
----------------------------------------------------------------------------*/
/******************************************************************************
(tell <output_file:string>)
Send output to file. Open file if not already open.
As in Edinburgh Prolog.
See Clocksin and Mellish, or Bratko for more details, or read the code!
******************************************************************************/
/* this stores the open output files */
struct named_ofile Open_ofiles[MAXOPEN];/* the value of MAXOPEN depends on the OS */
/* this stores the open input files */
struct named_ifile Open_ifiles[MAXOPEN];/* the value of MAXOPEN depends on the OS */
void ini_named_files()
{
int i;
Open_ofiles[0].o_filename = "user";
Open_ofiles[0].o_fp = stdout;
for(i = 1 ; i < MAXOPEN; i++)
{
Open_ofiles[i].o_filename = "";
Open_ofiles[i].o_fp = NULL;
}
Open_ifiles[0].i_filename = "user";
Open_ifiles[0].i_fp = stdin;
for(i = 1 ; i < MAXOPEN; i++)
{
Open_ifiles[i].i_filename = "";
Open_ifiles[i].i_fp = NULL;
}
}
open_output(filename)
char *filename;
{
int i, unused;
FILE *ofp;
for(i = 0, unused = MAXOPEN; i < MA